#region Copyright
//Copyright 2008 PivDev

//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at

//   http://www.apache.org/licenses/LICENSE-2.0

//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License. 
#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.Xml;
using EnvDTE;
using VSLangProj;
using System.Xml.XPath;
using System.IO;
using System.Data.SqlClient;
using System.Collections;


namespace CRMAddin
{
	public partial class AddinControl : UserControl
	{
		protected ArrayList nodeList = new ArrayList( );
		protected TreeNode lastNode , firstNode;
		private string serverName = "";
		private string password = "";
		private string userName = "";
		private string dbEngine = "";
		private string xmlConfigFile = "";
		private ToolStrip pGridTStrip;
		private ConfigValues objConfigVal;
		private EnvDTE80.DTE2 _objApplication;
		private bool addinInit = false;
		private bool configLoaded = false;

		public EnvDTE80.DTE2 ObjApplication
		{
			get { return _objApplication; }
			set { _objApplication = value; }
		}

		#region Initialisation
		public AddinControl ( )
		{

			InitializeComponent( );
			//ObjApplication = (EnvDTE80.DTE2)Application.o;
			if (addinInit) return;

			#region GUI Initailisation
			foreach (Control ts in pGrid.Controls)
			{
				pGridTStrip = ts as ToolStrip;
				if (pGridTStrip != null)
				{
					pGridTStrip.AllowMerge = true;
					ToolStripManager.Merge( toolStrip2 , pGridTStrip );
					break;
				}
			}

			toolStrip2.Hide( );
			tsDispLinkTable.Enabled = false;
			#endregion
			addinInit = true;
			#region Load tables from last config

			RegistryKey savedKey = Registry.CurrentUser.OpenSubKey( "PivotalVSSAddin" );

			if (savedKey != null)
			{
				if (savedKey.GetValue( "ServerName" ) == null) serverName = "";
				else serverName = ( string ) savedKey.GetValue( "ServerName" );
				if (savedKey.GetValue( "Password" ) == null) password = "";
				else password = ( string ) savedKey.GetValue( "Password" );
				if (savedKey.GetValue( "UserName" ) == null) userName = "";
				else userName = ( string ) savedKey.GetValue( "UserName" );
				if (savedKey.GetValue( "XMLFile" ) == null) xmlConfigFile = "";
				else xmlConfigFile = ( string ) savedKey.GetValue( "XMLFile" );
				if (savedKey.GetValue( "DBEngine" ) == null) dbEngine = "";
				else dbEngine = ( string ) savedKey.GetValue( "DBEngine" );

				if (!( serverName == "" | userName == "" || dbEngine == "" ))
				{
					PopulateTV( );
					statusLabel.Text = "Connected to " + serverName;
				}

				#region Load Config Values from file
				if (xmlConfigFile != "")
				{
					if (!loadConfigFile( false ))
					{
						MessageBox.Show( "No Configuration is loaded. Please select the Configuration Load button" , "No Config" , MessageBoxButtons.OK );
					}
				}
				#endregion
			}
			else statusLabel.Text = "Not Connected";
			#endregion

			ToolTip propTT = new ToolTip( );

			propTT.SetToolTip( pGrid , "Heelo" );


		}
		#endregion

		#region Events
		private void tsConnect_Click ( object sender , EventArgs e )
		{
			try
			{
				DSNChooser dsnChooserObj = new DSNChooser( );
				dsnChooserObj.ShowDialog( );

				serverName = dsnChooserObj.serverName;
				password = dsnChooserObj.password;
				userName = dsnChooserObj.userName;
				dbEngine = dsnChooserObj.DBEngine;

				dsnChooserObj.Close( );

				if (!( serverName == "" | userName == "" ))
				{
					if (!PopulateTV( ))
					{
						statusLabel.Text = "Not Connected";
						return;
					}

					RegistryKey savedKey = Registry.CurrentUser.OpenSubKey( "PivotalVSSAddin" , true );
					if (savedKey == null)
					{
						savedKey = Registry.CurrentUser.CreateSubKey( "PivotalVSSAddin" );

						savedKey.SetValue( "ServerName" , serverName );
						savedKey.SetValue( "Password" , password );
						savedKey.SetValue( "UserName" , userName );
						savedKey.SetValue( "DBEngine" , dbEngine );

					}
					else
					{
						savedKey.SetValue( "ServerName" , serverName );
						savedKey.SetValue( "Password" , password );
						savedKey.SetValue( "UserName" , userName );
						savedKey.SetValue( "DBEngine" , dbEngine );
					}



					statusLabel.Text = "Connected to " + serverName;
				}
				else
				{
					statusLabel.Text = "Not Connected";
					tvMain.Nodes.Clear( );
				}
			}
			catch (Exception exc)
			{

				throw new Exception( exc.Message , exc );
			}
		}

		private void tsConfig_Click ( object sender , EventArgs e )
		{
			loadConfigFile( true );
		}

		private void tvMain_ItemDrag ( object sender , ItemDragEventArgs e )
		{
			if (!configLoaded)
			{
				MessageBox.Show( cnsts.msgNoConfig , cnsts.msgNoConfigCap , MessageBoxButtons.OK , MessageBoxIcon.Warning );
				return;
			}
			TreeNode dragNode = ( TreeNode ) e.Item;
			// if you are dragging something other than the highlighted ones
			if (!nodeList.Contains( dragNode ))
			{
				removePaintFromNodes( );
				nodeList.Clear( );
				nodeList.Add( dragNode );
			}

			// sort the nodes, so does not matter how you selected them

			nodeList.Sort( new nodeComparer( ) );
			string dragString = "";
			switch (dragNode.Name)
			{
				case "Table":
					foreach (TreeNode dNode in nodeList)
					{
						dragString += buildTable( dNode ) + Environment.NewLine;
					}
					break;
				case "Fields":
					foreach (TreeNode dNode in nodeList)
					{
						dragString += buildAllFields( dNode ) + Environment.NewLine;
					}

					break;
				case "Field":
					foreach (TreeNode dNode in nodeList)
					{
						dragString += buildField( dNode ) + Environment.NewLine;
					}
					break;
				case "Queries":
					foreach (TreeNode dNode in nodeList)
					{
						dragString += buildAllQueries( dNode ) + Environment.NewLine;
					}
					break;
				case "Query":
					foreach (TreeNode dNode in nodeList)
					{
						dragString += buildQuery( dNode ) + Environment.NewLine;
					}
					break;
				case "Disconnected":
					foreach (TreeNode dNode in nodeList)
					{
						dragString += buildDiscField( dNode ) + Environment.NewLine;
					}
					break;
				case "Tab":
					foreach (TreeNode dNode in nodeList)
					{
						dragString += buildTab( dNode ) + Environment.NewLine;
					}
					break;
				case "Segment":
					foreach (TreeNode dNode in nodeList)
					{
						dragString += buildSegment( dNode ) + Environment.NewLine;
					}
					break;
				default:
					return;

			}
			DoDragDrop( dragString , DragDropEffects.Copy );
			//MessageBox.Show("Dragging");
		}

		private void tvMain_BeforeExpand ( object sender , TreeViewCancelEventArgs e )
		{
			switch (e.Node.Name)
			{
				case "Table":
					PopulateTV2ndLevel( e.Node );
					break;
				case "Fields":
					//PopulateFields(e.Node);
					break;
				case "Queries":
					//PopulateQueries(e.Node);
					break;
				case "Forms":
					//PopulateForms(e.Node);
					PopulateTabsForForms( e.Node );
					break;
				case "Form":
					PopulateSegmentsForTabs( e.Node );
					break;
				case "Tab":
					PopulateFieldsForSegments( e.Node );
					break;
				case "Segment":
					PopulateButtonsForBSs( e.Node );
					PopulateEventsForFormFields( e.Node );
					break;
				case "ButtonSet":
					PopulateButtonsForBSs( e.Node );
					PopulateEventsForFormFields( e.Node );
					break;
				//case "Field":
				//    PopulatePropField(e.Node);
				//    break;
			}
		}

		private void tvMain_BeforeSelect ( object sender , TreeViewCancelEventArgs e )
		{

			bool bControl = ( ModifierKeys == Keys.Control );
			bool bShift = ( ModifierKeys == Keys.Shift );

			if (!bControl && !bShift)
			{
				switch (e.Node.Name)
				{
					case "Field":
						PopulatePropField( e.Node );
						break;
					case "Form":
						PopulatePropForm( e.Node );
						break;
					case "Tab":
						PopulatePropTab( e.Node );
						break;
					case "Segment":
						PopulatePropSegment( e.Node );
						break;
					case "ButtonSet":
					case "Disconnected":
					case "FormField":
						PopulatePropFormField( e.Node );
						break;
					default:
						pGrid.SelectedObject = null;
						break;
				}
			}
			else
			{
				pGrid.SelectedObject = null;
				if (bControl && nodeList.Contains( e.Node ))
				{
					e.Cancel = true;
					removePaintFromNodes( );
					nodeList.Remove( e.Node );
					paintSelectedNodes( );
				}
				else
				{
					lastNode = e.Node;
					if (!bShift) firstNode = e.Node;
				}
			}
		}

		private void tvMain_AfterSelect ( object sender , TreeViewEventArgs e )
		{
			bool bControl = ( ModifierKeys == Keys.Control );
			bool bShift = ( ModifierKeys == Keys.Shift );

			if (bControl)
			{
				if (!nodeList.Contains( e.Node ))
				{
					if (nodeList.Count == 0)
					{
						nodeList.Add( e.Node );
					}
					// only add if they have same parent
					else if (( ( TreeNode ) nodeList[ 0 ] ).Parent == e.Node.Parent)
					{
						nodeList.Add( e.Node );
					}
					else
					{
						removePaintFromNodes( );
						nodeList.Clear( );
					}
				}
				else
				{
					removePaintFromNodes( );
					nodeList.Remove( e.Node );
				}
				paintSelectedNodes( );
			}
			else if (bShift)
			{
				if (( ( TreeNode ) nodeList[ 0 ] ).Parent == e.Node.Parent)
				{
					TreeNode bottomNode = e.Node;
					TreeNode topNode = firstNode;

					if (bottomNode.Index <= topNode.Index)
					{
						bottomNode = firstNode;
						topNode = e.Node;
					}

					for (int i = topNode.Index ; i < bottomNode.Index ; i++)
					{
						if (topNode.Parent == null)
						{
							if (!nodeList.Contains( tvMain.Nodes[ i ] )) nodeList.Add( tvMain.Nodes[ i ] );
						}
						else if (!nodeList.Contains( topNode.Parent.Nodes[ i ] )) nodeList.Add( topNode.Parent.Nodes[ i ] );
					}

				}
				else
				{
					removePaintFromNodes( );
					nodeList.Clear( );
				}

				firstNode = e.Node;
				paintSelectedNodes( );

			}
			else
			{
				removePaintFromNodes( );
				nodeList.Clear( );
				nodeList.Add( e.Node );
				firstNode = e.Node;
			}
		}

		private void tsDispLinkTable_Click ( object sender , EventArgs ea )
		{
			try
			{
				switch (pGrid.SelectedObject.GetType( ).ToString( ))
				{
					case "CRMAddin.propertyFKField":
						propertyFKField currentField = ( propertyFKField ) pGrid.SelectedObject;

						foreach (TreeNode tn in tvMain.Nodes)
						{
							if (tn.Text == currentField.LinkedTable)
							{
								PopulateFields( tn.Nodes[ "Fields" ] );
								foreach (TreeNode tnField in tn.Nodes[ "Fields" ].Nodes)
								{
									if (tnField.Text == currentField.LinkedField)
									{

										tvMain.Nodes[ tn.Index ].Nodes[ "Fields" ].Expand( );

										tvMain.SelectedNode = tvMain.Nodes[ tn.Index ].Nodes[ "Fields" ];

										break;
									}
								}
								break;
							}

						}
						break;
					case "CRMAddin.propertyFormField":
						propertyFormField currentFormField = ( propertyFormField ) pGrid.SelectedObject;

						foreach (TreeNode tn in tvMain.Nodes)
						{
							if (tn.Text == currentFormField.TableName)
							{
								PopulateFields( tn.Nodes[ "Fields" ] );
								foreach (TreeNode tnField in tn.Nodes[ "Fields" ].Nodes)
								{
									if (tnField.Text == currentFormField.FieldName)
									{
										tvMain.Nodes[ tn.Index ].Nodes[ "Fields" ].Expand( );
										tvMain.SelectedNode = tvMain.Nodes[ tn.Index ].Nodes[ "Fields" ].Nodes[ tnField.Index ];
										break;
									}
								}
								break;
							}
						}
						break;
				}
			}
			catch (Exception e)
			{

				throw new Exception( e.Message , e );
			}
		}

		private void contextMenuStrip1_Opening ( object sender , CancelEventArgs e )
		{
			if (tvMain.SelectedNode.Name != "Table")
			{
				e.Cancel = true;
			}

		}

		private void tvMain_NodeMouseClick ( object sender , TreeNodeMouseClickEventArgs e )
		{
			if (e.Button == MouseButtons.Right)
			{
				tvMain.SelectedNode = e.Node;
			}
		}

		private void dataToolStripMenuItem_Click ( object sender , EventArgs e )
		{
			if (tvMain.SelectedNode.Name != "Table") return;

			if (!configLoaded)
			{
				MessageBox.Show( cnsts.msgNoConfig , cnsts.msgNoConfigCap , MessageBoxButtons.OK , MessageBoxIcon.Warning );
				return;
			}
			Project objProject;

			if (ObjApplication.Solution.Count == 0)
			{
				MessageBox.Show( "There is no open Solution" + Environment.NewLine + Environment.NewLine + "Please open a solution to create code in" ,
																								"No Solution" , MessageBoxButtons.OK , MessageBoxIcon.Exclamation );
				return;
			}

			//Check to see if there is more than one project
			if (ObjApplication.Solution.Projects.Count >= 1)
			{
				ProjectChooser objPC = new ProjectChooser( );

				foreach (Project currentProj in ObjApplication.Solution.Projects)
				{

					if (currentProj.Kind == VSLangProj.PrjKind.prjKindCSharpProject) objPC.comboBox1.Items.Add( new cboItem( currentProj.Name , currentProj.UniqueName ) );
				}

				objPC.ShowDialog( );

				if (objPC.projectName == "") return;
				else objProject = ObjApplication.Solution.Projects.Item( objPC.projectName );

				objPC.Dispose( );
			}
			else
			{
				objProject = ObjApplication.Solution.Projects.Item( 0 );
			}

			string curNameSpace = objProject.Properties.Item( "RootNamespace" ).Value.ToString( );



			string directoryName = Path.GetDirectoryName( objProject.FullName );
			string classFullpath = directoryName + "\\" + tvMain.SelectedNode.Text + ".cs";

			if (File.Exists( classFullpath ))
			{
				if (MessageBox.Show( "The file " + classFullpath + " already exists." +
																						Environment.NewLine + Environment.NewLine +
																						"Do you want to overwrite this file and replace with new class?" ,
																						"File exists" , MessageBoxButtons.YesNo , MessageBoxIcon.Exclamation )
																						== DialogResult.Yes)
				{
					File.Delete( classFullpath );
				}
				else return;
			}

			string createdClass = CreateDataClass( tvMain.SelectedNode , curNameSpace );
			StreamWriter sw = File.CreateText( classFullpath );
			//sw.Encoding
			sw.Write( createdClass );

			sw.Close( );

			objProject.ProjectItems.AddFromFile( classFullpath );

		}

		private void formScriptToolStripMenuItem_Click ( object sender , EventArgs e )
		{

			if (tvMain.SelectedNode.Name != "Table") return;

			if (!configLoaded)
			{
				MessageBox.Show( cnsts.msgNoConfig , cnsts.msgNoConfigCap , MessageBoxButtons.OK , MessageBoxIcon.Warning );
				return;
			}

			Project objProject;

			if (ObjApplication.Solution.Count == 0)
			{
				MessageBox.Show( "There is no open Solution" + Environment.NewLine + Environment.NewLine + "Please open a solution to create code in" ,
																								"No Solution" , MessageBoxButtons.OK , MessageBoxIcon.Exclamation );
				return;
			}
			//Check to see if there is more than one project
			if (ObjApplication.Solution.Projects.Count >= 1)
			{
				ProjectChooser objPC = new ProjectChooser( );

				foreach (Project currentProj in ObjApplication.Solution.Projects)
				{

					if (currentProj.Kind == VSLangProj.PrjKind.prjKindCSharpProject) objPC.comboBox1.Items.Add( new cboItem( currentProj.Name , currentProj.UniqueName ) );
				}

				objPC.ShowDialog( );

				if (objPC.projectName == "") return;
				else objProject = ObjApplication.Solution.Projects.Item( objPC.projectName );

				objPC.Dispose( );
			}
			else
			{
				objProject = ObjApplication.Solution.Projects.Item( 0 );
			}

			string curNameSpace = objProject.Properties.Item( "RootNamespace" ).Value.ToString( );



			string directoryName = Path.GetDirectoryName( objProject.FullName );
			string classFullpath = directoryName + "\\" + tvMain.SelectedNode.Text + ".cs";

			if (File.Exists( classFullpath ))
			{
				if (MessageBox.Show( "The file " + classFullpath + " already exists." +
																						Environment.NewLine + Environment.NewLine +
																						"Do you want to overwrite this file and replace with new class?" ,
																						"File exists" , MessageBoxButtons.YesNo , MessageBoxIcon.Exclamation )
																						!= DialogResult.Yes)
				{
					File.Delete( classFullpath );
				}
			}

			string createdClass = CreateFSClass( tvMain.SelectedNode , curNameSpace );
			StreamWriter sw = File.CreateText( classFullpath );
			//sw.Encoding
			sw.Write( createdClass );

			sw.Close( );

			objProject.ProjectItems.AddFromFile( classFullpath );
		}


		#endregion

		#region Populate GUI Stuff

		#region Treeview Population
		private TreeNode[ ] getDefaultNodes ( )
		{
			TreeNode fieldsNode = new TreeNode( );
			fieldsNode.Text = "Fields";
			fieldsNode.Tag = "Fields";
			fieldsNode.Name = "Fields";
			//fieldsNode.k

			TreeNode queriesNode = new TreeNode( );
			queriesNode.Text = "Queries";
			queriesNode.Name = "Queries";

			TreeNode formsNode = new TreeNode( );
			formsNode.Text = "Forms";
			formsNode.Name = "Forms";

			return new TreeNode[ ] { fieldsNode , queriesNode , formsNode };
		}

		private TreeNode[ ] getDefaultFormNodes ( )
		{
			TreeNode segNode = new TreeNode( );
			segNode.Text = "Fields";
			segNode.Tag = "Fields";
			segNode.Name = "Fields";
			//fieldsNode.k

			TreeNode queriesNode = new TreeNode( );
			queriesNode.Text = "Queries";
			queriesNode.Name = "Queries";

			TreeNode formsNode = new TreeNode( );
			formsNode.Text = "Forms";
			formsNode.Name = "Forms";

			return new TreeNode[ ] { segNode , queriesNode , formsNode };
		}

		private bool PopulateTV ( )
		{
			tvMain.Nodes.Clear( );

			string sqlStatement = "Select RN_FLAG, RN_VALUE from RSYS_SYSTEM_FLAGS where rn_flag = 'Database Mode'";

			DataRow drTestConnection = CreateDataRow( sqlStatement , "RSYS_SYSTEM_FLAGS" );

			if (!drTestConnection[ "RN_VALUE" ].ToString( ).Equals( "Meta" ))
			{
				MessageBox.Show( "The database " + serverName + "\\" + userName + " does not appear to be a Business Module connection" + Environment.NewLine + "Please select a different database" );

				return false;
			}
			sqlStatement = "Select table_name, tables_id from tables order by table_name";

			DataSet ds = CreateDataset( sqlStatement , "tables" );

			foreach (DataRow dr in ds.Tables[ "tables" ].Rows)
			{
				TreeNode tn = new TreeNode( );
				tn.Text = dr[ "table_name" ].ToString( );
				tn.Tag = dr[ "tables_id" ];
				tn.Name = "Table";
				tn.Nodes.AddRange( getDefaultNodes( ) );

				tvMain.Nodes.Add( tn );
			}
			ds.Dispose( );
			return true;
		}

		private void PopulateTV2ndLevel ( TreeNode parentNode )
		{
			try
			{
				PopulateFields( parentNode.Nodes[ "Fields" ] );

				PopulateQueries( parentNode.Nodes[ "Queries" ] );

				PopulateForms( parentNode.Nodes[ "Forms" ] );
			}
			catch (Exception e)
			{
				throw new Exception( e.Message , e );
			}
		}

		private void PopulateFields ( TreeNode fieldsNode )
		{
			try
			{

				#region Get the system fields
				string sqlCommand = "select field_name, dictionary_name, type,TABLE_FIELDS_ID  from table_fields, data_dictionary" +
																																																				" where dictionary_id =  data_dictionary_id" +
																																																				" and tables_id = ";

				sqlCommand = sqlCommand + ConvertPivId( fieldsNode.Parent.Tag );
				sqlCommand = sqlCommand + " and (primary_key_ordinal = 1 or field_name in ('Rn_Descriptor','Rn_Create_Date','Rn_Create_User','Rn_Edit_Date','Rn_Edit_User'))";
				sqlCommand = sqlCommand + " order by ordinal";


				DataSet ds = CreateDataset( sqlCommand , "table_fields" );

				fieldsNode.Nodes.Clear( );
				foreach (DataRow dr in ds.Tables[ "table_fields" ].Rows)
				{
					//TreeNode fieldsNode = parentNode.Nodes.Find("Fields", true)[0];
					TreeNode fieldNode = fieldsNode.Nodes.Add( dr[ "field_name" ].ToString( ) );
					fieldNode.Name = "Field";
					fieldNode.Tag = dr[ "TABLE_FIELDS_ID" ];
					//parentNode.Nodes["Fields"].Nodes.Add(dr["field_name"].ToString());
				}
				#endregion

				#region Get Everything else
				sqlCommand = "select field_name, dictionary_name, type,TABLE_FIELDS_ID  from table_fields, data_dictionary" +
																																																				" where dictionary_id =  data_dictionary_id" +
																																																				" and tables_id = ";

				sqlCommand += ConvertPivId( fieldsNode.Parent.Tag );
				sqlCommand += " and (( primary_key_ordinal = 0 or primary_key_ordinal is null) " +
																								"and field_name not in " +
																								"('Rn_Descriptor','Rn_Create_Date','Rn_Create_User','Rn_Edit_Date','Rn_Edit_User'))";
				sqlCommand = sqlCommand + " order by field_name";

				ds = CreateDataset( sqlCommand , "table_fields" );
				foreach (DataRow dr in ds.Tables[ "table_fields" ].Rows)
				{
					TreeNode fieldNode = fieldsNode.Nodes.Add( dr[ "field_name" ].ToString( ) );
					fieldNode.Name = "Field";
					fieldNode.Tag = dr[ "TABLE_FIELDS_ID" ];
				}

				#endregion
			}
			catch (Exception)
			{

				throw;
			}
		}

		private void PopulateQueries ( TreeNode queriesNode )
		{
			try
			{
				string sqlCommand = "select saved_lookup_name from saved_lookups" +
																								" where table_id = ";
				sqlCommand = sqlCommand + ConvertPivId( queriesNode.Parent.Tag );
				sqlCommand = sqlCommand + " order by saved_lookup_name asc";

				DataSet ds = CreateDataset( sqlCommand , "saved_lookups" );

				queriesNode.Nodes.Clear( );
				foreach (DataRow dr in ds.Tables[ "saved_lookups" ].Rows)
				{
					//TreeNode fieldsNode = parentNode.Nodes.Find("Fields", true)[0];
					TreeNode queryNode = queriesNode.Nodes.Add( dr[ "saved_lookup_name" ].ToString( ) );
					queryNode.Name = "Query";
					//parentNode.Nodes["Fields"].Nodes.Add(dr["field_name"].ToString());
				}
			}
			catch (Exception)
			{

				throw;
			}
		}

		private void PopulateForms ( TreeNode formsNode )
		{
			try
			{
				string sqlCommand = "select ng_form_name,  ng_form_id from ng_form" +
																								" where table_id =  ";


				sqlCommand = sqlCommand + ConvertPivId( formsNode.Parent.Tag );
				sqlCommand = sqlCommand + " order by ng_form_name asc";

				DataSet ds = CreateDataset( sqlCommand , "ng_form" );

				formsNode.Nodes.Clear( );
				foreach (DataRow dr in ds.Tables[ "ng_form" ].Rows)
				{
					//TreeNode fieldsNode = parentNode.Nodes.Find("Fields", true)[0];
					TreeNode formNode = formsNode.Nodes.Add( dr[ "ng_form_name" ].ToString( ) );
					formNode.Tag = dr[ "ng_form_id" ];
					formNode.Name = "Form";
					//PopulateTabs(formNode);
					//parentNode.Nodes["Fields"].Nodes.Add(dr["field_name"].ToString());
				}
			}
			catch (Exception)
			{

				throw;
			}
		}

		private void PopulateTabsForForms ( TreeNode formsNode )
		{
			foreach (TreeNode formNode in formsNode.Nodes)
			{
				PopulateTabForForm( formNode );
			}
		}

		private void PopulateTabForForm ( TreeNode formNode )
		{
			try
			{
				string sqlCommand = "SELECT   form_tab_title, ng_form_tab_id, is_tab_anchored, is_tab_hidden, ordinal " +
																						"FROM ng_form_tab " +
																						"WHERE ng_form_id = ";
				sqlCommand += ConvertPivId( formNode.Tag );
				sqlCommand += " ORDER BY ordinal ASC";

				DataSet ds = CreateDataset( sqlCommand , "ng_form_tab" );

				formNode.Nodes.Clear( );

				foreach (DataRow dr in ds.Tables[ "ng_form_tab" ].Rows)
				{
					TreeNode tabNode = formNode.Nodes.Add( dr[ "form_tab_title" ].ToString( ) );
					tabNode.Tag = dr[ "ng_form_tab_id" ];
					tabNode.Name = "Tab";
					if (System.Convert.ToBoolean( dr[ "is_tab_anchored" ] )) tabNode.NodeFont = new Font( tvMain.Font , FontStyle.Bold );

					if (System.Convert.ToBoolean( dr[ "is_tab_hidden" ] )) tabNode.NodeFont = new Font( tvMain.Font , FontStyle.Bold );
				}
			}
			catch (Exception)
			{

				throw;
			}
		}

		private void PopulateSegmentsForTabs ( TreeNode formNode )
		{
			foreach (TreeNode tabNode in formNode.Nodes)
			{
				PopulateSegmentsForTab( tabNode );
			}
		}

		private void PopulateSegmentsForTab ( TreeNode tabNode )
		{
			string sqlCommand = "SELECT form_segment_title, is_title_hidden, " +
																							"is_secondary,  ng_form_Segment_id, is_segment_hidden " +
																							"FROM ng_form_segment " +
																							"WHERE ng_form_tab_id = ";
			sqlCommand += ConvertPivId( tabNode.Tag );
			sqlCommand += " ORDER BY ordinal ASC";

			DataSet ds = CreateDataset( sqlCommand , "ng_form_segment" );

			tabNode.Nodes.Clear( );

			foreach (DataRow dr in ds.Tables[ "ng_form_segment" ].Rows)
			{
				TreeNode segNode = tabNode.Nodes.Add( dr[ "form_segment_title" ].ToString( ) );
				segNode.Tag = dr[ "ng_form_segment_id" ];
				segNode.Name = "Segment";
				if (System.Convert.ToBoolean( dr[ "is_segment_hidden" ] )) segNode.NodeFont = new Font( tvMain.Font , FontStyle.Italic );
				if (!dr[ "is_secondary" ].Equals( DBNull.Value ))
				{
					if (System.Convert.ToBoolean( dr[ "is_secondary" ] )) segNode.NodeFont = new Font( tvMain.Font , FontStyle.Bold );
				}
			}
		}

		private void PopulateFieldsForSegments ( TreeNode tabNode )
		{
			foreach (TreeNode segNode in tabNode.Nodes)
			{
				PopulateFieldsForSegment( segNode );
			}
		}

		private void PopulateFieldsForSegment ( TreeNode segNode )
		{

			string sqlCommand = "SELECT field_title, is_button, visible, button_name, is_static_text, " +
																							"ng_form_field_id, is_buttonset, disconnected_type " +
																							"FROM ng_form_field " +
																							"WHERE  (parent_field_id IS NULL OR parent_field_id = '0000000000000000') " +
																							"AND form_segment_id = ";
			sqlCommand += ConvertPivId( segNode.Tag );
			sqlCommand += " ORDER BY ordinal ASC";

			DataSet ds = CreateDataset( sqlCommand , "ng_form_field" );

			segNode.Nodes.Clear( );
			foreach (DataRow dr in ds.Tables[ "ng_form_field" ].Rows)
			{

				TreeNode fieldNode = segNode.Nodes.Add( dr[ "field_title" ].ToString( ) );
				if (Convert.ToBoolean( dr[ "is_static_text" ] )) fieldNode.Text = dr[ "button_name" ].ToString( );
				fieldNode.Tag = dr[ "ng_form_field_id" ];
				fieldNode.Name = "FormField";
				if (System.Convert.ToBoolean( dr[ "visible" ] ) == false) fieldNode.NodeFont = new Font( tvMain.Font , FontStyle.Italic );
				if (System.Convert.ToBoolean( dr[ "is_buttonset" ] ))
				{
					fieldNode.Name = "ButtonSet";
					fieldNode.Text += " (BS)";
				}
				else if (System.Convert.ToBoolean( dr[ "is_button" ] )) fieldNode.Text += " (B)";
				if (!dr[ "disconnected_type" ].Equals( DBNull.Value ))
				{
					fieldNode.Name = "Disconnected";
					fieldNode.ForeColor = Color.Pink;
				}
			}
		}

		private void PopulateButtonsForBSs ( TreeNode segNode )
		{
			foreach (TreeNode formFieldNode in segNode.Nodes)
			{
				if (formFieldNode.Name == "ButtonSet") PopulateButtonsForBS( formFieldNode );
			}
		}

		private void PopulateButtonsForBS ( TreeNode formFieldNode )
		{
			string sqlCommand = "SELECT field_title, visible, " +
																							"ng_form_field_id, is_buttonset, is_button " +
																							"FROM ng_form_field " +
																							"WHERE parent_field_id = ";

			sqlCommand += ConvertPivId( formFieldNode.Tag );
			sqlCommand += " ORDER BY ordinal ASC";

			DataSet ds = CreateDataset( sqlCommand , "ng_form_field" );

			formFieldNode.Nodes.Clear( );
			foreach (DataRow dr in ds.Tables[ "ng_form_field" ].Rows)
			{
				TreeNode fieldNode = formFieldNode.Nodes.Add( dr[ "field_title" ].ToString( ) );
				fieldNode.Tag = dr[ "ng_form_field_id" ];
				fieldNode.Name = "FormField";
				if (System.Convert.ToBoolean( dr[ "visible" ] ) == false) fieldNode.NodeFont = new Font( tvMain.Font , FontStyle.Italic );
				if (System.Convert.ToBoolean( dr[ "is_buttonset" ] ))
				{
					fieldNode.Name = "ButtonSet";
					fieldNode.Text += " (BS)";
				}
				else if (System.Convert.ToBoolean( dr[ "is_button" ] )) fieldNode.Text += " (B)";
			}
		}

		private void PopulateEventsForFormFields ( TreeNode segNode )
		{
			foreach (TreeNode formFieldNode in segNode.Nodes)
			{
				if (formFieldNode.Name != "ButtonSet") PopulateEventsForFormField( formFieldNode );
			}
		}

		private void PopulateEventsForFormField ( TreeNode formFieldNode )
		{
			string sqlStatement = "SELECT event_name, event_hook_id " +
																							"FROM event_hook " +
																							"WHERE form_field_id = ";
			sqlStatement += ConvertPivId( formFieldNode.Tag );

			DataSet ds = CreateDataset( sqlStatement , "event_hook" );

			formFieldNode.Nodes.Clear( );
			foreach (DataRow dr in ds.Tables[ "event_hook" ].Rows)
			{
				TreeNode eventNode = formFieldNode.Nodes.Add( dr[ "event_name" ].ToString( ) );
				eventNode.Tag = dr[ "event_hook_id" ];
				eventNode.Name = "Event";
			}
		}
		#endregion

		#region Property Grid Population
		private void PopulatePropField ( TreeNode fieldNode )
		{
			string sqlCommand = "select FIELD_NAME, DICTIONARY_NAME,TYPE, FIELD_LENGTH, FOREIGN_KEY_FIELD_ID" +
																							" from table_fields, data_dictionary" +
																							" where data_dictionary_id = dictionary_id" +
																							" and table_fields_id = ";
			sqlCommand = sqlCommand + ConvertPivId( fieldNode.Tag );

			DataRow dr = CreateDataRow( sqlCommand , "table_fields" );


			// Linking field check
			if (!dr[ "FOREIGN_KEY_FIELD_ID" ].Equals( DBNull.Value ))
			{
				//  if (!dr["FOREIGN_KEY_FIELD_ID"].Equals(new byte[] {
				byte[ ] blankByte = new byte[ ] { ( byte ) 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
				if (!blankByte.Equals( ( byte[ ] ) dr[ "FOREIGN_KEY_FIELD_ID" ] ))
				{
					propertyFKField dispField = new propertyFKField( );
					dispField.Name = dr[ "FIELD_NAME" ].ToString( );
					dispField.Type = dr[ "TYPE" ].ToString( );
					dispField.DictName = dr[ "DICTIONARY_NAME" ].ToString( );
					dispField.Length = dr[ "FIELD_LENGTH" ].ToString( );

					string fkFieldID = System.BitConverter.ToString( ( byte[ ] ) dr[ "FOREIGN_KEY_FIELD_ID" ] ).Replace( "-" , "" );
					sqlCommand = "select TF.FIELD_NAME as Field_Name, TF.TABLE_FIELDS_ID as Field_Id, T.TABLE_NAME as Table_Name, T.TABLES_ID as Table_Id" +
																			" from TABLE_FIELDS TF, TABLES T" +
																			" where T.TABLES_ID = TF.TABLES_ID " +
																			" and TABLE_FIELDS_ID = '" + fkFieldID + "'";

					dr = CreateDataRow( sqlCommand , "TF" );

					dispField.LinkedTable = dr[ "Table_Name" ].ToString( );
					dispField.LinkedTableId = dr[ "Table_Id" ];
					dispField.LinkedField = dr[ "Field_Name" ].ToString( );
					dispField.LinkedFieldId = dr[ "Field_Id" ];
					pGrid.SelectedObject = dispField;
					tsDispLinkTable.Enabled = true;
				}
			}
			else
			{
				propertyField dispField = new propertyField( );
				dispField.Name = dr[ "FIELD_NAME" ].ToString( );
				dispField.Type = dr[ "TYPE" ].ToString( );
				dispField.DictName = dr[ "DICTIONARY_NAME" ].ToString( );
				dispField.Length = dr[ "FIELD_LENGTH" ].ToString( );

				pGrid.SelectedObject = dispField;
				tsDispLinkTable.Enabled = false;
			}



		}

		private void PopulatePropForm ( TreeNode formNode )
		{
			string sqlCommand = "SELECT f.ng_form_title, f.tabs_uniform_width, s.server_script_name, " +
																					"c.client_script_name " +
																					"FROM ng_form f " +
																					"LEFT OUTER JOIN server_script s ON f.server_script_id = s.server_script_id " +
																					"LEFT OUTER JOIN client_script c ON f.global_client_script_id = c.client_script_id " +
																					"WHERE ng_form_id = ";
			sqlCommand += ConvertPivId( formNode.Tag );

			DataRow dr = CreateDataRow( sqlCommand , "ng_form" );

			propertyForm dispForm = new propertyForm( );

			dispForm.DispName = dr[ "ng_form_title" ].ToString( );
			dispForm.TabEqual = dr[ "tabs_uniform_width" ].ToString( );
			dispForm.CSName = dr[ "client_script_name" ].ToString( );
			dispForm.ServerName = dr[ "server_script_name" ].ToString( );

			pGrid.SelectedObject = dispForm;
			tsDispLinkTable.Enabled = false;
		}

		private void PopulatePropTab ( TreeNode tabNode )
		{
			string sqlCommand = "SELECT form_tab_name, is_tab_hidden, is_tab_anchored " +
																					"FROM ng_form_tab " +
																					"WHERE ng_form_tab_id = ";
			sqlCommand += ConvertPivId( tabNode.Tag );

			DataRow dr = CreateDataRow( sqlCommand , "ng_form_tab" );

			propertyTab dispTab = new propertyTab( );
			dispTab.Anchored = dr[ "is_tab_anchored" ].ToString( );
			dispTab.TabHidden = dr[ "is_tab_hidden" ].ToString( );
			dispTab.TabName = dr[ "form_tab_name" ].ToString( );

			pGrid.SelectedObject = dispTab;
			tsDispLinkTable.Enabled = false;
		}

		private void PopulatePropSegment ( TreeNode segNode )
		{
			string sqlCommand = "SELECT shrinkable, is_secondary, form_segment_name, is_title_hidden, " +
																							"sort_descending, prohibit_add, prohibit_delete, read_only, " +
																							"in_place_new, is_segment_hidden, is_web_segment, is_search_result_list, " +
																							"records_per_page, is_collapsed " +
																							"FROM ng_form_segment " +
																							"WHERE ng_form_segment_id = ";
			sqlCommand += ConvertPivId( segNode.Tag );

			DataRow dr = CreateDataRow( sqlCommand , "ng_form_segment" );

			if (Convert.ToBoolean( dr[ "is_secondary" ] ))
			{
				propertySegSec dispSeg = new propertySegSec( );
				dispSeg.Shrinkable = dr[ "shrinkable" ].ToString( );
				dispSeg.Secondary = dr[ "is_secondary" ].ToString( );
				dispSeg.SegName = dr[ "form_segment_name" ].ToString( );
				dispSeg.TitleHidden = dr[ "is_title_hidden" ].ToString( );
				dispSeg.SortDesc = dr[ "sort_descending" ].ToString( );
				dispSeg.ProhAdd = dr[ "prohibit_add" ].ToString( );
				dispSeg.ProhDel = dr[ "prohibit_delete" ].ToString( );
				dispSeg.ReadOnly = dr[ "read_only" ].ToString( );
				dispSeg.InPlaceNew = dr[ "in_place_new" ].ToString( );
				dispSeg.SegHidden = dr[ "is_segment_hidden" ].ToString( );
				dispSeg.SRList = dr[ "is_search_result_list" ].ToString( );
				dispSeg.RecPerPage = dr[ "records_per_page" ].ToString( );
				dispSeg.IsCollapsed = dr[ "is_collapsed" ].ToString( );


				pGrid.SelectedObject = dispSeg;
				tsDispLinkTable.Enabled = false;
			}
			else
			{
				propertySeg dispSeg = new propertySeg( );
				dispSeg.WebSeg = dr[ "is_web_segment" ].ToString( );
				dispSeg.Shrinkable = dr[ "shrinkable" ].ToString( );
				dispSeg.SegName = dr[ "form_segment_name" ].ToString( );
				dispSeg.TitleHidden = dr[ "is_title_hidden" ].ToString( );
				dispSeg.SegHidden = dr[ "is_segment_hidden" ].ToString( );
				dispSeg.IsCollapsed = dr[ "is_collapsed" ].ToString( );


				pGrid.SelectedObject = dispSeg;
				tsDispLinkTable.Enabled = false;
			}

		}

		private void PopulatePropFormField ( TreeNode fFieldNode )
		{
			string sqlStatement = "SELECT field_title, on_toolbar, is_button, visible, required, read_only, " +
																									"line_count, foreign_key_filter_id, filter_parameter_map, field_id, " +
																									"is_separator, button_name, uri_text, is_static_text, is_icon, icon_url, " +
																									"icon_tooltip, icon_priority, is_buttonset, tf.field_name, " +
																									"disconnected_type, t.table_name, sl.saved_lookup_name, " +
																									"dd.dictionary_name " +
																							"FROM ng_form_field ff " +
																									"LEFT OUTER JOIN table_fields tf " +
																											"ON field_id = tf.table_fields_id " +
																									"LEFT OUTER JOIN saved_lookups sl " +
																											"ON foreign_key_filter_id = sl.saved_lookups_id " +
																									"LEFT OUTER JOIN tables t " +
																											"ON tf.tables_id = t.tables_id " +
																									"LEFT OUTER JOIN data_dictionary dd " +
																											"ON ff.disconnected_type = dd.data_dictionary_id " +
																							"WHERE ff.ng_form_field_id =";

			sqlStatement += ConvertPivId( fFieldNode.Tag );

			DataRow dr = CreateDataRow( sqlStatement , "ng_form_field" );

			#region Seperator
			if (Convert.ToBoolean( dr[ "is_separator" ] ))
			{
				pGrid.SelectedObject = null;
				tsDispLinkTable.Enabled = false;
				return;
			}
			#endregion

			#region Button / Button Set
			if (Convert.ToBoolean( dr[ "is_buttonset" ] ) | Convert.ToBoolean( dr[ "is_button" ] ))
			{
				propertyButton propButton = new propertyButton( );
				propButton.ButtonName = dr[ "button_name" ].ToString( );
				propButton.Hidden = dr[ "visible" ].ToString( );
				propButton.OnToolbar = dr[ "on_toolbar" ].ToString( );
				pGrid.SelectedObject = propButton;
				tsDispLinkTable.Enabled = false;

				return;
			}
			#endregion

			#region Diconnected Field
			if (!dr[ "disconnected_type" ].Equals( DBNull.Value ))
			{
				propertyDisconn propDisc = new propertyDisconn( );
				propDisc.DictionaryName = dr[ "dictionary_name" ].ToString( );
				propDisc.Name = dr[ "button_name" ].ToString( );
				propDisc.Required = dr[ "required" ].ToString( );

				pGrid.SelectedObject = propDisc;
				tsDispLinkTable.Enabled = false;
				return;
			}
			#endregion

			#region Icon
			if (!dr[ "is_icon" ].Equals( DBNull.Value ))
			{
				if (Convert.ToBoolean( dr[ "is_icon" ] ))
				{
					propertyIcon propIcon = new propertyIcon( );
					propIcon.IconName = dr[ "field_title" ].ToString( );
					propIcon.Priority = dr[ "icon_priority" ].ToString( );
					propIcon.Tooltip = dr[ "icon_tooltip" ].ToString( );
					propIcon.URL = dr[ "icon_url" ].ToString( );

					pGrid.SelectedObject = propIcon;
					tsDispLinkTable.Enabled = false;
					return;
				}
			}

			#endregion

			#region Static Text
			if (Convert.ToBoolean( dr[ "is_static_text" ] ))
			{
				propertyStatic propStat = new propertyStatic( );
				propStat.FullText = dr[ "field_title" ].ToString( );
				propStat.Hidden = dr[ "visible" ].ToString( );
				pGrid.SelectedObject = propStat;

				tsDispLinkTable.Enabled = false;
				return;
			}
			#endregion

			#region Field
			propertyFormField propFField = new propertyFormField( );

			propFField.FieldId = dr[ "field_id" ];
			propFField.FieldName = dr[ "field_name" ].ToString( );
			propFField.TableName = dr[ "table_name" ].ToString( );
			propFField.Visible = dr[ "visible" ].ToString( );
			propFField.Required = dr[ "required" ].ToString( );
			propFField.LineCount = dr[ "line_count" ].ToString( );

			pGrid.SelectedObject = propFField;
			tsDispLinkTable.Enabled = true;
			#endregion

		}
		#endregion

		#region Load Config File

		private bool loadConfigFile ( bool newConfig )
		{
			configLoaded = false;
			objConfigVal = new ConfigValues( );
			if (newConfig || xmlConfigFile.Equals( "" ))
			{
				OpenFileDialog fd = new OpenFileDialog( );

				fd.InitialDirectory = "C:\\";
				fd.Filter = "XML Files (*.xml)|*.xml";
				fd.Title = "Please select a configuration file";
				fd.FilterIndex = 1;
				if (fd.ShowDialog( ) == DialogResult.OK)
				{
					try
					{
						XPathDocument xmlPathDoc = new XPathDocument( fd.FileName );
						XPathNavigator nav = xmlPathDoc.CreateNavigator( );
						XPathExpression xExpress;
						xExpress = nav.Compile( "Preferences/Table" );
						XPathNodeIterator iterator = nav.Select( xExpress );

						XmlDocument xmlDoc = new XmlDocument( );
						xmlDoc.Load( fd.FileName );

						xmlConfigFile = fd.FileName;
						RegistryKey savedKey = Registry.CurrentUser.OpenSubKey( "PivotalVSSAddin" , true );

						if (savedKey != null)
						{
							savedKey.SetValue( "XMLFile" , fd.FileName );
						}
						else
						{
							throw new Exception( "Can not find registry key" );
						}

						ConfigRead objConfig = new ConfigRead( objConfigVal , xmlDoc );
						configLoaded = true;
						return true;
					}
					catch (Exception)
					{
						MessageBox.Show( "Error: Can not open config File" , "Error" , MessageBoxButtons.OK , MessageBoxIcon.Error );
						configLoaded = false;
						return false;
					}
				}
				else
				{
					configLoaded = false;
					return false;
				}
			}
			else
			{
				XmlDocument xmlDoc = new XmlDocument( );

				xmlDoc.Load( xmlConfigFile );
				ConfigRead objConfig = new ConfigRead( objConfigVal , xmlDoc );
				configLoaded = true;
				return true;
			}
		}
		#endregion

		#endregion

		#region Utilities
		#region Build Strings for Dragging etc
		private string buildAllFields ( TreeNode fieldsNode )
		{
			int tabCount = 0;
			// Populate incase there isn't any data
			PopulateFields( fieldsNode );
			StringBuilder returnSB = new StringBuilder( );
			if (objConfigVal.FieldSubClass != "")
			{
				returnSB.AppendLine( objConfigVal.FieldSubClassPrefix + objConfigVal.FieldSubClass );
				returnSB.AppendLine( "{" );
				returnSB.AppendLine( );
				tabCount++;
			}
			if (objConfigVal.FieldRegion != "")
			{
				returnSB.AppendLine( addTab( "#region " + objConfigVal.FieldRegion , tabCount ) );
				returnSB.AppendLine( );
				tabCount++;
			}
			foreach (TreeNode fieldNode in fieldsNode.Nodes)
			{
				returnSB.AppendLine( buildField( fieldNode , tabCount ) );
			}
			if (objConfigVal.FieldRegion != "")
			{
				returnSB.AppendLine( );
				returnSB.AppendLine( addTab( "#endregion" , --tabCount ) );
			}
			if (objConfigVal.FieldSubClass != "") returnSB.AppendLine( ); returnSB.AppendLine( "}" );
			return returnSB.ToString( );
		}

		private string buildAllFields ( TreeNode fieldsNode , int tabCount )
		{
			// Populate incase there isn't any data
			PopulateFields( fieldsNode );
			StringBuilder returnSB = new StringBuilder( );
			if (objConfigVal.FieldSubClass != "")
			{
				returnSB.AppendLine( addTab( objConfigVal.FieldSubClassPrefix + objConfigVal.FieldSubClass , tabCount ) );
				returnSB.AppendLine( addTab( "{" , tabCount ) );
				returnSB.AppendLine( );
				tabCount++;
			}
			if (objConfigVal.FieldRegion != "")
			{
				returnSB.AppendLine( addTab( "#region " + objConfigVal.FieldRegion , tabCount ) );
				returnSB.AppendLine( );
				// tabCount++;
			}
			foreach (TreeNode fieldNode in fieldsNode.Nodes)
			{
				returnSB.AppendLine( buildField( fieldNode , tabCount ) );
			}
			if (objConfigVal.FieldRegion != "")
			{
				//tabCount--;
				returnSB.AppendLine( );
				returnSB.AppendLine( addTab( "#endregion" , tabCount ) );
			}
			if (objConfigVal.FieldSubClass != "")
			{
				tabCount--;
				returnSB.AppendLine( );
				returnSB.AppendLine( addTab( "}" , tabCount ) );
			}
			return returnSB.ToString( );
		}

		private string buildField ( TreeNode fieldNode )
		{
			string returnString = objConfigVal.FieldPrefix;
			string fieldName = fieldNode.Text;
			if (fieldNode.Index != 0)
			{
				foreach (string replaceString in objConfigVal.FieldPrefixRemove)
				{
					if (fieldName.Length < replaceString.Length) break;
					if (fieldName.Substring( 0 , replaceString.Length ) == replaceString)
					{
						fieldName = fieldName.Substring( replaceString.Length , fieldName.Length - replaceString.Length );
						break;
					}
				}
			}
			if (objConfigVal.CapField) returnString = returnString + fieldName.ToUpper( );
			else returnString = returnString + fieldName;

			returnString = returnString + objConfigVal.FieldSuffix + " = \"" + fieldNode.Text + "\";";
			return returnString;
		}

		private string buildField ( TreeNode fieldNode , int tabCount )
		{
			string returnString = addTab( objConfigVal.FieldPrefix , tabCount );
			string fieldName = fieldNode.Text;
			if (fieldNode.Index != 0)
			{
				foreach (string replaceString in objConfigVal.FieldPrefixRemove)
				{
					if (fieldName.Length < replaceString.Length) break;
					if (fieldName.Substring( 0 , replaceString.Length ) == replaceString)
					{
						fieldName = fieldName.Substring( replaceString.Length , fieldName.Length - replaceString.Length );
						break;
					}
				}
			}
			if (objConfigVal.CapField) returnString = returnString + fieldName.ToUpper( );
			else returnString = returnString + fieldName;

			returnString = returnString + objConfigVal.FieldSuffix + " = \"" + fieldNode.Text + "\";";
			return returnString;
		}

		private string buildTable ( TreeNode tableNode )
		{
			StringBuilder returnSB = new StringBuilder( );

			if (objConfigVal.TableRegion != "") returnSB.AppendLine( "#region " + objConfigVal.TableRegion ); returnSB.AppendLine( );

			if (objConfigVal.TableName != "") returnSB.AppendLine( objConfigVal.TablePrefix + objConfigVal.TableName + " = \"" + tableNode.Text + "\";" );
			else
			{
				string tableName = tableNode.Text;
				foreach (string replaceString in objConfigVal.TablePrefixRemove)
				{
					if (tableName.Length < replaceString.Length) break;
					if (tableName.Substring( 0 , replaceString.Length ) == replaceString)
					{
						tableName = tableName.Substring( replaceString.Length , tableName.Length - replaceString.Length );
						break;
					}
				}
				if (objConfigVal.CapTable) returnSB.AppendLine( objConfigVal.TablePrefix + tableName.ToUpper( ) + objConfigVal.TableSuffix + " = \"" + tableNode.Text + "\";" );
				else returnSB.AppendLine( objConfigVal.TablePrefix + tableName + objConfigVal.TableSuffix + " = \"" + tableNode.Text + "\";" );
			}
			returnSB.AppendLine( );

			returnSB.AppendLine( buildAllFields( tableNode.Nodes[ "Fields" ] ) );
			returnSB.AppendLine( );

			returnSB.AppendLine( buildAllQueries( tableNode.Nodes[ "Queries" ] ) );
			returnSB.AppendLine( );


			if (objConfigVal.TableRegion != "") returnSB.AppendLine( "#endregion " );
			return returnSB.ToString( );
		}

		private string buildTable ( TreeNode tableNode , int tabCount )
		{
			StringBuilder returnSB = new StringBuilder( );

			if (objConfigVal.TableRegion != "")
			{
				returnSB.AppendLine( addTab( "#region " , tabCount ) + objConfigVal.TableRegion );
				returnSB.AppendLine( );
				//tabCount++;
			}

			if (objConfigVal.TableName != "")
			{
				returnSB.AppendLine( addTab( objConfigVal.TablePrefix + objConfigVal.TableName + " = \"" + tableNode.Text + "\";" , tabCount ) );
			}
			else
			{
				string tableName = tableNode.Text;
				foreach (string replaceString in objConfigVal.TablePrefixRemove)
				{
					if (tableName.Length < replaceString.Length) break;
					if (tableName.Substring( 0 , replaceString.Length ) == replaceString)
					{
						tableName = tableName.Substring( replaceString.Length , tableName.Length - replaceString.Length );
						break;
					}
				}
				if (objConfigVal.CapTable)
				{
					returnSB.AppendLine( addTab( objConfigVal.TablePrefix + tableName.ToUpper( ) + objConfigVal.TableSuffix + " = \"" + tableNode.Text + "\";" , tabCount ) );
				}
				else returnSB.AppendLine( addTab( objConfigVal.TablePrefix + tableName + objConfigVal.TableSuffix + " = \"" + tableNode.Text + "\";" , tabCount ) );
			}
			returnSB.AppendLine( );

			returnSB.AppendLine( buildAllFields( tableNode.Nodes[ "Fields" ] , tabCount ) );
			returnSB.AppendLine( );

			returnSB.AppendLine( buildAllQueries( tableNode.Nodes[ "Queries" ] , tabCount ) );
			returnSB.AppendLine( );


			if (objConfigVal.TableRegion != "")
			{
				//tabCount--;
				returnSB.AppendLine( addTab( "#endregion" , tabCount ) );
			}
			return returnSB.ToString( );
		}

		private string buildAllQueries ( TreeNode queriesNode )
		{
			int tabCount = 0;
			// Populate incase there isn't any data
			PopulateQueries( queriesNode );
			StringBuilder returnSB = new StringBuilder( );

			if (objConfigVal.QuerySubClass != "")
			{
				returnSB.AppendLine( objConfigVal.QuerySubClassPrefix + objConfigVal.QuerySubClass );
				returnSB.AppendLine( "{" );
				returnSB.AppendLine( );
				tabCount++;
			}
			if (objConfigVal.QueryRegion != "")
			{
				returnSB.AppendLine( addTab( "#region " + objConfigVal.QueryRegion , tabCount ) );
				returnSB.AppendLine( );
				tabCount++;
			}
			foreach (TreeNode queryNode in queriesNode.Nodes)
			{
				returnSB.AppendLine( buildQuery( queryNode , tabCount ) );
			}

			if (objConfigVal.QueryRegion != "")
			{
				returnSB.AppendLine( );
				returnSB.AppendLine( addTab( "#endregion" , --tabCount ) );
			}
			if (objConfigVal.QuerySubClass != "") returnSB.AppendLine( ); returnSB.AppendLine( "}" );

			return returnSB.ToString( );
		}

		private string buildAllQueries ( TreeNode queriesNode , int tabCount )
		{
			// Populate incase there isn't any data
			PopulateQueries( queriesNode );
			StringBuilder returnSB = new StringBuilder( );

			if (objConfigVal.QuerySubClass != "")
			{
				returnSB.AppendLine( addTab( objConfigVal.QuerySubClassPrefix + objConfigVal.QuerySubClass , tabCount ) );
				returnSB.AppendLine( addTab( "{" , tabCount ) );
				returnSB.AppendLine( );
				tabCount++;
			}
			if (objConfigVal.QueryRegion != "")
			{
				returnSB.AppendLine( addTab( "#region " + objConfigVal.QueryRegion , tabCount ) );
				returnSB.AppendLine( );
				// tabCount++;
			}
			foreach (TreeNode queryNode in queriesNode.Nodes)
			{
				returnSB.AppendLine( buildQuery( queryNode , tabCount ) );
			}

			if (objConfigVal.QueryRegion != "")
			{
				//tabCount--;
				returnSB.AppendLine( );
				returnSB.AppendLine( addTab( "#endregion" , tabCount ) );
			}
			if (objConfigVal.QuerySubClass != "")
			{
				tabCount--;
				returnSB.AppendLine( );
				returnSB.AppendLine( addTab( "}" , tabCount ) );
			}

			return returnSB.ToString( );
		}

		private string buildQuery ( TreeNode queryNode )
		{
			string returnString = objConfigVal.QueryPrefix;
			string queryName = queryNode.Text;
			foreach (string replaceString in objConfigVal.QueryPrefixRemove)
			{
				if (replaceString != "")
				{
					if (queryName.Length < replaceString.Length) break;
					if (queryName.Substring( 0 , replaceString.Length ) == replaceString)
					{
						queryName = queryName.Substring( replaceString.Length , queryName.Length - replaceString.Length );
						break;
					}
				}
			}
			foreach (string replaceString in objConfigVal.QueryReplaceChars)
			{
				if (replaceString != "") queryName = queryName.Replace( replaceString , objConfigVal.QueryReplaceWith );
			}

			if (objConfigVal.QueryReplaceEndChars) queryName = queryName.TrimEnd( new char[ ] { objConfigVal.QueryReplaceWith[ 0 ] } );
			if (objConfigVal.QueryReplaceStartChars) queryName = queryName.TrimStart( objConfigVal.QueryReplaceWith[ 0 ] );

			if (objConfigVal.CapQuery) returnString = returnString + queryName.ToUpper( ) + objConfigVal.QuerySuffix;
			else returnString = returnString + queryName + objConfigVal.QuerySuffix;
			returnString = returnString + " = \"" + queryNode.Text + "\";";

			return returnString;
		}

		private string buildQuery ( TreeNode queryNode , int tabCount )
		{
			string returnString = addTab( objConfigVal.QueryPrefix , tabCount );
			string queryName = queryNode.Text;
			foreach (string replaceString in objConfigVal.QueryPrefixRemove)
			{
				if (replaceString != "")
				{
					if (queryName.Length < replaceString.Length) break;
					if (queryName.Substring( 0 , replaceString.Length ) == replaceString)
					{
						queryName = queryName.Substring( replaceString.Length , queryName.Length - replaceString.Length );
						break;
					}
				}
			}
			foreach (string replaceString in objConfigVal.QueryReplaceChars)
			{
				if (replaceString != "") queryName = queryName.Replace( replaceString , objConfigVal.QueryReplaceWith );
			}

			if (objConfigVal.QueryReplaceEndChars) queryName = queryName.TrimEnd( new char[ ] { objConfigVal.QueryReplaceWith[ 0 ] } );
			if (objConfigVal.QueryReplaceStartChars) queryName = queryName.TrimStart( objConfigVal.QueryReplaceWith[ 0 ] );

			if (objConfigVal.CapQuery) returnString = returnString + queryName.ToUpper( ) + objConfigVal.QuerySuffix;
			else returnString = returnString + queryName + objConfigVal.QuerySuffix;
			returnString = returnString + " = \"" + queryNode.Text + "\";";

			return returnString;
		}

		private string buildDiscField ( TreeNode discFieldNode )
		{
			return buildDiscField( discFieldNode , 0 );
		}

		private string buildDiscField ( TreeNode discFieldNode , int tabCount )
		{
			string returnString = addTab( objConfigVal.DiscPrefix , tabCount );

			string discField = replaceChars(removePrefix( discFieldNode.Text , objConfigVal.DiscPrefixRemove , new string[ ] { " " }, "" ), 
																		objConfigVal.DiscReplaceChars, objConfigVal.DiscReplaceWith, objConfigVal.DiscReplaceStartChars, objConfigVal.DiscReplaceEndChars);

			if (objConfigVal.CapDisc) returnString += discField.ToUpper( );
			returnString += objConfigVal.DiscSuffix + " = \"" + discFieldNode.Text + "\";";
			return returnString;
		}

		private string buildSegment ( TreeNode segNode )
		{
			return buildSegment( segNode , 0 );
		}

		private string buildSegment ( TreeNode segNode , int tabCount )
		{
			if (objConfigVal.CapSeg) return addTab( objConfigVal.SegPrefix , tabCount ) +
						replaceChars( removePrefix( segNode.Text , objConfigVal.SegPrefixRemove , new string[ ] { " " }, "" ).ToUpper( ) ,
						objConfigVal.SegReplaceChars , objConfigVal.SegReplaceWith , objConfigVal.SegReplaceStartChars , objConfigVal.SegReplaceEndChars ) +
						objConfigVal.SegSuffix + " = \"" + segNode.Text + "\";";
			else return addTab( objConfigVal.SegPrefix , tabCount ) +
					 replaceChars( removePrefix( segNode.Text , objConfigVal.SegPrefixRemove , new string[ ] { " " }, "" ) ,
					 objConfigVal.SegReplaceChars , objConfigVal.SegReplaceWith , objConfigVal.SegReplaceStartChars , objConfigVal.SegReplaceEndChars ) +
					 objConfigVal.SegSuffix + " = \"" + segNode.Text + "\";";
		}

		private string buildTab ( TreeNode tabNode )
		{
			return buildTab( tabNode , 0 );
		}

		private string buildTab ( TreeNode tabNode , int tabCount )
		{
			if (objConfigVal.CapTab) return addTab( objConfigVal.TabPrefix , tabCount ) +
							replaceChars( removePrefix( tabNode.Text , objConfigVal.TabPrefixRemove , new string[ ] { " " }, "" ).ToUpper( ) ,
							objConfigVal.TabReplaceChars , objConfigVal.TabReplaceWith , objConfigVal.TabReplaceStartChars , objConfigVal.TabReplaceEndChars ) +
							objConfigVal.TabSuffix + " = \"" + tabNode.Text + "\";";
			else return addTab( objConfigVal.TabPrefix , tabCount ) +
						 replaceChars( removePrefix( tabNode.Text , objConfigVal.TabPrefixRemove , new string[ ] { " " }, "" ) ,
						 objConfigVal.TabReplaceChars , objConfigVal.TabReplaceWith , objConfigVal.TabReplaceStartChars , objConfigVal.TabReplaceEndChars ) +
						 objConfigVal.TabSuffix + " = \"" + tabNode.Text + "\";";
		}

		private string buildForm ( TreeNode formNode )
		{
			return buildForm( formNode , 0 );
		}

		private string buildForm ( TreeNode formNode , int tabCount )
		{
			if (objConfigVal.CapForm) return addTab( objConfigVal.FormPrefix , tabCount ) +
							replaceChars( removePrefix( formNode.Text , objConfigVal.FormPrefixRemove , new string[ ] { " " }, "" ).ToUpper( ) ,
							objConfigVal.FormReplaceChars , objConfigVal.FormReplaceWith , objConfigVal.FormReplaceStartChars , objConfigVal.FormReplaceEndChars ) +
							objConfigVal.FormSuffix + " = \"" + formNode.Text + "\";";
			else return addTab( objConfigVal.FormPrefix , tabCount ) +
							replaceChars( removePrefix( formNode.Text , objConfigVal.FormPrefixRemove , new string[ ] { " " }, "" ) ,
							objConfigVal.FormReplaceChars , objConfigVal.FormReplaceWith , objConfigVal.FormReplaceStartChars , objConfigVal.FormReplaceEndChars ) +
							objConfigVal.FormSuffix + " = \"" + formNode.Text + "\";";
		}
		#endregion

		#region Database Access
		private DataSet CreateDataset ( string sqlStatement , string TableName )
		{

			DataSet ds = new DataSet( );

			if (dbEngine.Equals( "Oracle" ))
			{
				OracleCommand oraComm = new OracleCommand( );
				OracleDataAdapter oraDA = new OracleDataAdapter( );
				OracleConnection conn = new OracleConnection( );
				try
				{
					string connectionString = "User Id=" + userName + ";Password=" + password + ";Data Source=" + serverName;
					conn.ConnectionString = connectionString;
					conn.Open( );

					oraComm.CommandText = sqlStatement;
					oraComm.Connection = conn;

					oraComm.CommandType = CommandType.Text;
					oraDA.SelectCommand = oraComm;

					oraDA.Fill( ds , TableName );

					return ds;
				}
				catch (Exception e)
				{
					throw new Exception( e.Message , e );
				}
				finally
				{
					if (oraComm != null)
					{
						( ( IDisposable ) oraComm ).Dispose( );
					}
					oraDA.Dispose( );
					conn.Dispose( );
					ds.Dispose( );
				}
			}
			else //SQL
			{
				SqlCommand sqlComm = new SqlCommand( );
				SqlConnection conn = new SqlConnection( );
				SqlDataAdapter sqlDA = new SqlDataAdapter( );
				try
				{
					string connectionString = "server=" + serverName + ";Trusted_Connection=yes;" +
														 "database=" + userName + "; " +
														 "connection timeout=30";
					conn.ConnectionString = connectionString;
					conn.Open( );

					sqlComm.CommandText = sqlStatement;
					sqlComm.Connection = conn;
					sqlComm.CommandType = CommandType.Text;
					sqlDA.SelectCommand = sqlComm;
					//SqlDataAdapter sqlDA = new SqlDataAdapter(sqlComm);
					sqlDA.Fill( ds , TableName );
					return ds;
				}
				catch (Exception e)
				{
					throw new Exception( e.Message , e );
				}
			}
		}

		private DataRow CreateDataRow ( string sqlStatement , string TableName )
		{
			DataSet ds = new DataSet( );
			if (dbEngine.Equals( "Oracle" ))
			{
				OracleCommand oraComm = new OracleCommand( );

				OracleDataAdapter oraDA = new OracleDataAdapter( );
				OracleConnection conn = new OracleConnection( );
				try
				{
					string connectionString = "User Id=" + userName + ";Password=" + password + ";Data Source=" + serverName;
					conn.ConnectionString = connectionString;
					conn.Open( );

					oraComm.CommandText = sqlStatement;
					oraComm.Connection = conn;

					oraComm.CommandType = CommandType.Text;
					oraDA.SelectCommand = oraComm;

					oraDA.Fill( ds , TableName );

					return ds.Tables[ TableName ].Rows[ 0 ];
				}
				catch (Exception e)
				{

					throw new Exception( e.Message , e );
				}
				finally
				{
					if (oraComm != null)
					{
						( ( IDisposable ) oraComm ).Dispose( );
					}
					oraDA.Dispose( );
					conn.Dispose( );
					ds.Dispose( );
				}
			}
			else //Microsoft SQL
			{
				SqlConnection conn = new SqlConnection( );
				try
				{
					string connectionString = "server=" + serverName + ";Trusted_Connection=yes;" +
														 "database=" + userName + "; " +
														 "connection timeout=30";
					conn.ConnectionString = connectionString;
					conn.Open( );

					SqlCommand sqlComm = new SqlCommand( sqlStatement , conn );
					SqlDataAdapter sqlDA = new SqlDataAdapter( sqlComm );
					sqlDA.Fill( ds , TableName );
					return ds.Tables[ TableName ].Rows[ 0 ];
				}
				catch (Exception e)
				{
					throw new Exception( e.Message , e );
				}
			}
		}

		#endregion

		#region Create Full Classes
		private string CreateDataClass ( TreeNode tableNode , string projNameSpace )
		{
			StringBuilder sbCode = new StringBuilder( );

			foreach (string usingString in objConfigVal.DBUsing)
			{
				sbCode.AppendLine( "using " + usingString + ";" );
			}

			sbCode.AppendLine( );
			sbCode.AppendLine( "namespace " + projNameSpace );
			sbCode.AppendLine( "{" );
			//int addNSCount = objConfigVal.DBAddNamespaces.Length;
			int tabCount = 0;
			foreach (string addNamespace in objConfigVal.DBAddNamespaces)
			{
				tabCount++;
				sbCode.AppendLine( addTab( "namespace " + addNamespace , tabCount ) );
				sbCode.AppendLine( addTab( "{" , tabCount ) );
			}


			sbCode.Append( addTab( objConfigVal.DBClassPrefix + tableNode.Text , ++tabCount ) );
			if (objConfigVal.DBInherits.Length != 0)
			{
				string inherits = " :";

				foreach (string inheritString in objConfigVal.DBInherits)
				{
					inherits += " " + inheritString + ",";
				}
				inherits = inherits.TrimEnd( ',' );
				sbCode.AppendLine( inherits );
			}
			else sbCode.AppendLine( );
			sbCode.AppendLine( addTab( "{" , tabCount ) );


			sbCode.AppendLine( buildTable( tableNode , tabCount + 1 ) );

			sbCode.AppendLine( buildFullForms( tableNode , tabCount ) );

			//add other classes

			foreach (ConfigValues.codeMethods codeMeths in objConfigVal.DBCodeMethods)
			{
				if (codeMeths.Region != "")
				{
					sbCode.AppendLine( addTab( "#region " + codeMeths.Region , ++tabCount ) );
				}

				foreach (ConfigValues.codeMethod codemeth in codeMeths.CodeMethod)
				{
					if (codemeth.Constructor) sbCode.AppendLine( prefixMethod( codemeth.Code.Replace( "$methodname$" , tableNode.Text ) , tabCount ) );
					else sbCode.AppendLine( prefixMethod( codemeth.Code , tabCount ) );
				}

				if (codeMeths.Region != "")
				{
					sbCode.AppendLine( addTab( "#endregion" , tabCount-- ) );
				}
				sbCode.AppendLine( );
			}

			sbCode.AppendLine( addTab( "}" , tabCount ) ); // end of class

			foreach (string addNamespace in objConfigVal.DBAddNamespaces)
			{
				tabCount--;
				sbCode.AppendLine( addTab( "}" , tabCount ) );
			}
			sbCode.AppendLine( "}" ); // End of namspace
			return sbCode.ToString( );
		}

		private string CreateFSClass ( TreeNode tableNode , string projNameSpace )
		{
			StringBuilder sbCode = new StringBuilder( );

			foreach (string usingString in objConfigVal.FSUsing)
			{
				sbCode.AppendLine( "using " + usingString + ";" );
			}

			sbCode.AppendLine( );
			sbCode.AppendLine( "namespace " + projNameSpace );
			sbCode.AppendLine( "{" );
			//int addNSCount = objConfigVal.DBAddNamespaces.Length;
			int tabCount = 0;
			foreach (string addNamespace in objConfigVal.FSAddNamespaces)
			{
				tabCount++;
				sbCode.AppendLine( addTab( "namespace " + addNamespace , tabCount ) );
				sbCode.AppendLine( addTab( "{" , tabCount ) );
			}


			sbCode.Append( addTab( objConfigVal.FSClassPrefix + tableNode.Text , ++tabCount ) );
			if (objConfigVal.FSInherits.Length != 0)
			{
				string inherits = " :";

				foreach (string inheritString in objConfigVal.FSInherits)
				{
					inherits += " " + inheritString + ",";
				}
				inherits = inherits.TrimEnd( ',' );
				sbCode.AppendLine( inherits );
			}
			else sbCode.AppendLine( );
			sbCode.AppendLine( addTab( "{" , tabCount ) );

			//Insert Formscript code

			if (objConfigVal.FSMethods.Region != "")
			{
				sbCode.AppendLine( addTab( "#region " , tabCount ) );
				sbCode.AppendLine( );
			}
			tabCount++;
			if (objConfigVal.FSMethods.SetSystem != null) sbCode.AppendLine(
																																	buildFSMethod( objConfigVal.FSMethods.SetSystem , tabCount , objConfigVal.FSMethods.Prefix ) );

			if (objConfigVal.FSMethods.AddForm != null) sbCode.AppendLine(
																																	 buildFSMethod( objConfigVal.FSMethods.AddForm , tabCount , objConfigVal.FSMethods.Prefix ) );
			if (objConfigVal.FSMethods.DeleteForm != null) sbCode.AppendLine(
																																	 buildFSMethod( objConfigVal.FSMethods.DeleteForm , tabCount , objConfigVal.FSMethods.Prefix ) );
			if (objConfigVal.FSMethods.Execute != null) sbCode.AppendLine(
																																	 buildFSMethod( objConfigVal.FSMethods.Execute , tabCount , objConfigVal.FSMethods.Prefix ) );
			if (objConfigVal.FSMethods.LoadForm != null) sbCode.AppendLine(
																																	 buildFSMethod( objConfigVal.FSMethods.LoadForm , tabCount , objConfigVal.FSMethods.Prefix ) );
			if (objConfigVal.FSMethods.NewForm != null) sbCode.AppendLine(
																																	 buildFSMethod( objConfigVal.FSMethods.NewForm , tabCount , objConfigVal.FSMethods.Prefix ) );
			if (objConfigVal.FSMethods.NewSec != null) sbCode.AppendLine(
																																	 buildFSMethod( objConfigVal.FSMethods.NewSec , tabCount , objConfigVal.FSMethods.Prefix ) );
			if (objConfigVal.FSMethods.SaveForm != null) sbCode.AppendLine(
																																	 buildFSMethod( objConfigVal.FSMethods.SaveForm , tabCount , objConfigVal.FSMethods.Prefix ) );

			tabCount--;

			if (objConfigVal.FSMethods.Region != "")
			{
				sbCode.AppendLine( );
				sbCode.AppendLine( addTab( "#endregion" , tabCount ) ); sbCode.AppendLine( );
			}



			//add other classes

			foreach (ConfigValues.codeMethods codeMeths in objConfigVal.FSCodeMethods)
			{
				if (codeMeths.Region != "")
				{
					sbCode.AppendLine( addTab( "#region " + codeMeths.Region , ++tabCount ) );
				}

				foreach (ConfigValues.codeMethod codemeth in codeMeths.CodeMethod)
				{
					if (codemeth.Constructor) sbCode.AppendLine( prefixMethod( codemeth.Code.Replace( "$methodname$" , tableNode.Text ) , tabCount ) );
					else sbCode.AppendLine( prefixMethod( codemeth.Code , tabCount ) );
				}

				if (codeMeths.Region != "")
				{
					sbCode.AppendLine( addTab( "#endregion" , tabCount-- ) );
				}
				sbCode.AppendLine( );
			}



			sbCode.AppendLine( addTab( "}" , tabCount ) ); // end of class

			foreach (string addNamespace in objConfigVal.FSAddNamespaces)
			{
				tabCount--;
				sbCode.AppendLine( addTab( "}" , tabCount ) );
			}
			sbCode.AppendLine( "}" ); // End of namspace
			return sbCode.ToString( );
		}

		private string buildFullForms ( TreeNode tableNode , int tabCount )
		{
			ArrayList discAL = new ArrayList( );
			ArrayList discNamesAL = new ArrayList( );
			ArrayList tabAL = new ArrayList( );
			ArrayList tabNamesAL = new ArrayList( );
			ArrayList segAL = new ArrayList( );
			ArrayList segNamesAL = new ArrayList( );

			StringBuilder returnSB = new StringBuilder( );

			if (objConfigVal.FormRegion != "")
			{
				returnSB.AppendLine( addTab( "#region " + objConfigVal.FormRegion , tabCount ) );
				returnSB.AppendLine( );
			}

			#region Get all the information to build string (Tabs / Segments & Disconnected Fields)
			PopulateForms( tableNode.Nodes[ "Forms" ] );
			foreach (TreeNode formNode in tableNode.Nodes[ "Forms" ].Nodes)
			{
				returnSB.AppendLine( buildForm( formNode , tabCount ) );
				PopulateTabForForm( formNode );
				foreach (TreeNode tabNode in formNode.Nodes) // go through the tabs of Form and add them to the array, so we can remove duplicates
				{
					if (tabNamesAL.IndexOf( tabNode.Text ) < 0)
					//if (tabNamesAL.BinarySearch( tabNode.Text ) < 0) // not found, add node & text to the 2 array lists
					{
						tabAL.Add( tabNode );
						tabNamesAL.Add( tabNode.Text );
					}
					PopulateSegmentsForTab( tabNode );
					foreach (TreeNode segNode in tabNode.Nodes) // go through all the segments of the tab, so we can remove duplicates
					{
						if (segNamesAL.IndexOf( segNode.Text ) < 0)
						{
							segNamesAL.Add( segNode.Text );
							segAL.Add( segNode );
						}
						PopulateFieldsForSegment( segNode );
						foreach (TreeNode discNode in segNode.Nodes) // go through all the fields of the segment so we can remove duplicates
						{
							if (discNode.Name == "Disconnected") // only want disconnected fields
							{
								if (discNamesAL.IndexOf( discNode.Text ) < 0)
								//if (discNamesAL.BinarySearch( discNode.Text ) < 0)
								{
									discAL.Add( discNode );
									discNamesAL.Add( discNode.Text );
								}
							}
						}
					}
				}
			}
			#endregion

			if (objConfigVal.FormRegion != "")
			{
				returnSB.AppendLine( );
				returnSB.AppendLine( addTab( "#endregion " , tabCount ) );
			}

			#region Tabs
			if (objConfigVal.TabRegion != "")
			{
				returnSB.AppendLine( addTab( "#region " + objConfigVal.TabRegion , tabCount ) );
				returnSB.AppendLine( );
			}

			foreach (TreeNode tabNode in tabAL)
			{
				returnSB.AppendLine( buildTab( tabNode , tabCount ) );
			}
			if (objConfigVal.TabRegion != "")
			{
				returnSB.AppendLine( );
				returnSB.AppendLine( addTab( "#endregion " , tabCount ) );
			}

			#endregion

			#region Segments

			if (objConfigVal.SegRegion != "")
			{
				returnSB.AppendLine( addTab( "#region " + objConfigVal.SegRegion , tabCount ) );
				returnSB.AppendLine( );
			}

			foreach (TreeNode segNode in segAL)
			{
				returnSB.AppendLine( buildTab( segNode , tabCount ) );
			}
			if (objConfigVal.SegRegion != "")
			{
				returnSB.AppendLine( );
				returnSB.AppendLine( addTab( "#endregion " , tabCount ) );
			}


			#endregion

			#region Disconnected Fields

			if (objConfigVal.DiscSubClass != "")
			{
				returnSB.AppendLine( addTab( objConfigVal.DiscSubClassPrefix + objConfigVal.DiscSubClass , tabCount ) );
				returnSB.AppendLine( addTab( "{" , tabCount ) );
				returnSB.AppendLine( );
				tabCount++;
			}

			if (objConfigVal.DiscRegion != "")
			{
				returnSB.AppendLine( addTab( "#region " + objConfigVal.DiscRegion , tabCount ) );
				returnSB.AppendLine( );
			}



			foreach (TreeNode discNode in discAL)
			{
				returnSB.AppendLine( buildDiscField( discNode , tabCount ) );
			}
			if (objConfigVal.DiscRegion != "")
			{
				returnSB.AppendLine( );
				returnSB.AppendLine( addTab( "#endregion " , tabCount ) );
			}

			if (objConfigVal.DiscSubClass != "")
			{
				tabCount--;
				returnSB.AppendLine( addTab( "}" , tabCount ) );
				returnSB.AppendLine( );
			}

			#endregion


			return returnSB.ToString( );
		}
		#endregion

		#region Formatting stufff

		private string replaceChars ( string oldString )
		{
			return oldString.Replace( " " , "_" ).Replace( ":" , "" );
		}

		private string ConvertPivId ( object idByteArray )
		{
			if (dbEngine.Equals( "SQL" ))
			{
				return "0x" + System.BitConverter.ToString( ( byte[ ] ) idByteArray ).Replace( "-" , "" );
			}
			else
			{
				return "'" + System.BitConverter.ToString( ( byte[ ] ) idByteArray ).Replace( "-" , "" ) + "'";
			}
		}

		private string addTab ( string toAppend , int noTabs )
		{
			for (int i = 1 ; i <= noTabs ; i++)
			{
				toAppend = "\t" + toAppend;
			}

			return toAppend;
		}

		private string prefixMethod ( string methodCode , int tabCount )
		{
			string tabsString = "\n";
			for (int i = 1 ; i <= tabCount ; i++)
			{
				tabsString += "\t";
			}
			return methodCode.Replace( "\n" , tabsString );
		}

		private string buildFSMethod ( ConfigValues.fsMethod fsMethod , int tabCount , string methodsPrefix )
		{
			if (fsMethod.UseDefault)
			{
				string returnString = "";
				string tryBlock = "{" + Environment.NewLine +
																								"\ttry" + Environment.NewLine +
																								"\t{";
				//+Environment.NewLine + 
				//                                      "\t\t";
				string catchBlock = "\t}" + Environment.NewLine +
																									 "\tcatch (Exception e)" + Environment.NewLine +
																									 "\t{" + Environment.NewLine +
																									 "\t\tthrow new PivotalApplicationException(e.Message, e, m_rdaSystem);" + Environment.NewLine +
																									 "\t}" + Environment.NewLine +
																									 "}";
				if (fsMethod.Prefix != "") returnString = addTab( fsMethod.Prefix + fsMethod.Code , tabCount );
				else returnString = addTab( methodsPrefix + fsMethod.Code , tabCount );

				if (fsMethod.TryCatch) returnString = returnString.Replace( "{" , tryBlock ).Replace( "}" , catchBlock );

				return prefixMethod( returnString , tabCount );
			}
			else return prefixMethod( fsMethod.Code , tabCount );
		}

		private string removePrefix ( string originalString , string[ ] prefixRemove )
		{
			return removePrefix( originalString , prefixRemove , new string[ ] { }, "" );
		}

		private string removePrefix ( string originalString , string[ ] prefixRemove , string[ ] replaceChars , string replaceWith )
		{
			string returnString = originalString;
			foreach (string replaceString in prefixRemove) // Remove prefixes
			{
				if (replaceString != "") // One of the prefixremove strings is empty
				{
					if (replaceString.Length < returnString.Length) // the prefix to remove is smaller than what we are searching for
					{
						if (returnString.Substring( 0 , replaceString.Length ) == replaceString) // We have a match
						{
							returnString = returnString.Substring( replaceString.Length , returnString.Length - replaceString.Length );
							// only remove one prefix
							break;
						}
					}
				}
			}

			foreach (string replaceChar in replaceChars)
			{
				if (replaceChar != "") returnString = returnString.Replace( replaceChar , replaceWith );
			}

			return returnString;
		}

		private string replaceChars ( string originalString , string[ ] replaceChars , string replaceWith , bool replaceStart , bool replaceEnd )
		{
			foreach (string replaceChar in replaceChars)
			{
				if (replaceChar != "") originalString = originalString.Replace( replaceChar , replaceWith );
			}
			if (replaceStart) originalString = originalString.TrimStart( new char[ ] { replaceWith[ 0 ] } );
			if (replaceEnd) originalString = originalString.TrimEnd( new char[ ] { replaceWith[ 0 ] } );

			return originalString;
		}
		#endregion

		#region Multiselect helpers

		protected void removePaintFromNodes ( )
		{
			if (nodeList.Count == 0) return;

			TreeNode n0 = ( TreeNode ) nodeList[ 0 ];
			Color back = n0.TreeView.BackColor;
			Color fore = n0.TreeView.ForeColor;

			foreach (TreeNode n in nodeList)
			{
				if (n.Name == "Disconnected")
				{
					n.BackColor = back;
					n.ForeColor = Color.Pink;
				}
				else
				{
					n.BackColor = back;
					n.ForeColor = fore;
				}
			}

		}

		protected void paintSelectedNodes ( )
		{
			foreach (TreeNode n in nodeList)
			{
				n.BackColor = SystemColors.Highlight;
				n.ForeColor = SystemColors.HighlightText;
			}
		}

		private class nodeComparer : IComparer
		{
			private IComparer nodeC = null;

			public nodeComparer ( )
			{
			}

			public int Compare ( object x , object y )
			{

				if (( x is TreeNode ) && ( y is TreeNode ))
				{
					TreeNode nodeX = ( TreeNode ) x;
					TreeNode nodeY = ( TreeNode ) y;
					if (nodeX == null && nodeY == null) return 0;
					else if (nodeX == null && nodeY != null) return -1;
					else if (nodeX != null && nodeY == null) return 1;
					else return nodeX.Text.CompareTo( nodeY.Text );
				}
				return -1;
			}
		}
		#endregion
		#endregion

		#region Constants
		internal class cnsts
		{
			internal const string msgNoConfig = "There is no condguration file loaded.\r\n Please use the Select Configuration Button before proceeding";

			internal const string msgNoConfigCap = "No Config Loaded";
		}
		#endregion

	}
}
